// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef _VIDEO_ENCODE_ENGINE_H
#define _VIDEO_ENCODE_ENGINE_H
#include <cstdint>
#include <string>
#include <atomic>
#include <mutex>
#include <memory>
#include "Log/logging.h"
#include "CPHVideoParams.h"
#include "VideoEncoderParam.h"


// 设置编码参数
struct SetEncodeParam {
    uint32_t frameRate; // 帧率0~60
    uint32_t bitrate;   // 1M~10M
    uint32_t gopSize;   // I帧间隔30~5000
    uint32_t profile;   // 66,77,100
};

using LOGCALLBACK = void(*)(const int level, const char *tag, const char *log);
class VideoEngine {
public:
    /*
     * @功能描述：构造函数
     */
    VideoEngine();

    /*
     * @功能描述：析构函数
     */
    ~VideoEngine();

    /*
     * @功能描述：初始化编码引擎
     * @参数 [in] encodeType：编码方式cpu
     * @参数 [in] param:编码参数结构体
     * @返回值：0 成功
     *         VMI_VIDEO_ENGINE_INIT_FAIL 初始化失败，
     *         VMI_VIDEO_ENGINE_PARAM_INVALID 无效参数
     */
    uint32_t InitEncoder(VideoEncoderParam &param);

    /*
     * @功能描述：开启编码引擎
     * @返回值：0 成功
     *         VMI_VIDEO_ENGINE_START_ERR 启动失败
     */
    uint32_t StartEncoder();

    /*
     * @功能描述：编码引擎状态获取
     * @参数 [out] stat：编码引擎状态
     * @返回值：VMI_SUCCESS 成功
     *         VMI_VIDEO_ENGINE_GET_STAT_ERR 返回获取状态失败
     */
    uint32_t GetEncoderStatus(EngineStat &stat);

    /*
     * @功能描述：编码引擎统计信息获取
     * @参数 [out] statics：编码引擎统计信息
     * @返回值：VMI_SUCCESS 成功
     *         VMI_VIDEO_ENGINE_GET_STAT_ERR 返回获取数据失败
     */
    uint32_t GetEncoderStatistics(EncoderStatistics &statics);

    /*
     * @功能描述：设置引擎编码参数
     * @参数 [in] statics：编码引擎设置参数结构体
     * @返回值：VMI_SUCCESS 成功
     *         VMI_VIDEO_ENGINE_CONFIG_ERR 设置错误
     */
    uint32_t SetEncoderParam(VideoEncoderParam &param);

    /*
     * @功能描述：编码引擎编码一帧数据接口
     * @参数 [in] src 待编码数据地址
     * @参数 [in] length 待编码数据长度
     * @返回值：VMI_SUCCESS 成功
     *         VMI_VIDEO_ENGINE_ENCODE_ERR 编码一帧错误
     *         VMI_VIDEO_ENGINE_ERR 编码引擎错误
     */
    uint32_t EncodeOneFrame(uint8_t *src, uint32_t length);
    //重载函数
    uint32_t EncodeOneFrame(uint8_t *src, uint32_t length, VideoParamExt& param);
    unsigned int getCurrentFPS(uint64_t &currentTs);
    uint32_t EncodeRepeatOneFrame(uint8_t *src, uint32_t length, VideoParamExt& param);
    
    /*
     * @功能描述：注册编码引擎发送数据回调函数
     * @参数 [in] callback 数据发送函数指针
     * @返回值：VMI_SUCCESS 成功
     *          VMI_VIDEO_ENGINE_REGISTER_ERR 注册函数错误
     */
    uint32_t RegisterEncoderCallback(VIDEOCALLBACK callback);

    /*
     * @功能描述：注册编码引擎日志回调函数
     * @参数 [in] logCallback 日志处理函数指针
     * @返回值：VMI_SUCCESS 成功
     *          VMI_VIDEO_ENGINE_REGISTER_ERR 注册函数错误
     */
    uint32_t RegisterLogCallback(LOGCALLBACK logCallback);

    /*
     * @功能描述：停止编码引擎
     * @返回值：VMI_SUCCES 成功
     *          VMI_VIDEO_ENGINE_STOP_ERR 停止操作失败
     */
    uint32_t StopEncoder();

    /*
     * @功能描述：销毁编码引擎
     * @返回值：VMI_SUCCESS 成功
     *          VMI_VIDEO_ENGINE_DESTROY_ERR 销毁编码引擎失败
     */
    uint32_t DestroyEncoder();

    /*
     * @功能描述：设置编码参数
     * @参数 [in] key 需要设置的编码参数
     * @参数 [in] value 需要设置的编码参数的值
     * @返回值：VMI_SUCCESS 成功
     *         unknow
     */
    uint32_t SetOpt(const std::string &key, const std::string value);

    /*
     * @功能描述：设置强制I帧
     * @返回值：VMI_SUCCESS 成功
     *          VMI_VIDEO_ENGINE_PARAM_UNSUPORTED 参数不支持
     */
    uint32_t SetEncoderKeyFrame();

    uint32_t GetEncoderResetFlag(bool &resetFlag);
    VIDEOCALLBACK m_videoCallback = nullptr; // 编码回调发送函数

    /**
     * @功能描述：从配置管理对象中获取最新配置
     * 
     */
    void reloadConfig();

private:
    bool m_firstFrame = true;
};

#endif  // _ENCODE_SERVICE_H_
